package com.sunfeng.a02;

import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.annotation.Resource;
import java.util.Map;

/**
 * @Author : 孙峰
 * @Description: 测试BeanFactory   DefaultListableBeanFactory
 * @Date : 2022/4/7  15:46
 */

public class TestBeanFactory {

    public static void main(String[] args) {
        // BeanFactory 主要学习DefaultListableBeanFactory
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();


        /**
         * Definition 定义
         */
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).getBeanDefinition();

        /**
         * 缺少解析注解解析功能 也就是Config 里面的注解不能被解析
         */
         beanFactory.registerBeanDefinition("config",beanDefinition);


        //   beanFactory.registerSingleton("config",Config.class);

        /**
         * 给beanFactory 添加常用的后处理器
         *  AutowiredAnnotationBeanPostProcessor
         *  CommonAnnotationBeanPostProcessor
         *
         */
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
        /**
         * Bean 的后置处理器 针对bean生命周期各个阶段提供扩展，例如@Autowired @Resource
         * >>>>>>>>>>>org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor@429bd883  ======Autowired
         * >>>>>>>>>>>org.springframework.context.annotation.CommonAnnotationBeanPostProcessor@4d49af10  ======Resource
         */
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanPostProcessor -> {
            System.out.println("beanPostProcessor>>>>>>>>>>>"+beanPostProcessor);
            beanFactory.addBeanPostProcessor(beanPostProcessor);
        });

        /**
         * BeanFactory 后处理器主要功能，补充了一些bean定义
         *  ConfigurationClassPostProcessor
         *  EventListenerMethodProcessor
         */
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            System.out.println("beanFactoryPostProcessor >>>>>>>>>>>"+beanFactoryPostProcessor);
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });


        /**
         * 此时  依赖注入的功能还没有
         */
//        System.out.println("*******");
     // System.out.println(beanFactory.getBean(Bean1.class).getBean2());




        System.out.println("=============");
        for (String beanDefinitionName : beanFactory.getBeanDefinitionNames()) {
            System.out.println(beanDefinitionName);
        }
        System.out.println("=============");
        System.out.println(beanFactory.getBean(Bean1.class).getBean2()+"11111111111111111");
        // 预实例化所有非懒加载单例Bean
        beanFactory.preInstantiateSingletons();


        /**
         * 此时  依赖注入的功能完成
         */
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        System.out.println(beanFactory.getBean(Bean1.class).getBean2());

        System.out.println(beanFactory.getBean(Bean1.class).getInter());



    }

    @Configuration
    static class Config{

        @Bean
        public Bean1 bean1(){
            return new Bean1();
        }
        @Bean
        public Bean2 bean2(){
            return new Bean2();
        }
        @Bean
        public Bean3 bean3(){
            return new Bean3();
        }
        @Bean
        public Bean4 bean4(){
            return new Bean4();
        }
    }
    @Configuration
    static class Config2{

        public Config2() {
        }
    }


    @Slf4j
    static class Bean1{
        public Bean1() {
            log.debug("Bean1 空参构造！！");
        }
        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }

        /**
         *  @Autowired 后处理器的优先级比较高  所以同时使用的话会注入bean3
         */
        @Autowired
        @Resource(name = "bean4")
        private Inter bean3;

        public Inter getInter() {
            return bean3;
        }

        @Override
        public String toString() {
            return "Bean1{" +
                    "bean2=" + bean2 +
                    ", bean3=" + bean3 +
                    '}';
        }
    }
    @Slf4j
    static class  Bean2{

        public Bean2() {
            log.debug("Bean2的 空参构造！！");
        }
    }
    interface Inter{}

    static class Bean3 implements Inter{


    }
    static class Bean4 implements Inter{

    }
}
